package com.xingda.packing.shunt.handle;

import com.xingda.packing.common.ScanCodeUtils;
import com.xingda.packing.domain.ProductBoxLocation;
import com.xingda.packing.domain.ShuntProductionLine;
import com.xingda.packing.domain.Wheel;
import com.xingda.packing.enums.*;
import com.xingda.packing.events.EventCreater;
import com.xingda.packing.http.WheelHttp;
import com.xingda.packing.rule.RuleUtilsV2;
import com.xingda.packing.shunt.ticket.ShuntTicket;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class ShuntHandle implements TaskHandleService {
    @Resource
    EventCreater eventCreater;
    @Resource
    RuleUtilsV2 ruleUtils;
    @Value("${com.xingda.area}")
    @Getter
    private String line;

    @Override
    public boolean accept(ShuntProductionLine productionLine, int area) {
        return checkTask(productionLine.getTaskTicketByArea(area), TaskType.SHUNT);
    }

    @Override
    public void process(ShuntProductionLine productionLine, int area) {
        ShuntTicket taskTicket = (ShuntTicket) productionLine.getTaskTicketByArea(area);
        Wheel wheel = taskTicket.getWheel();
        log.info("====process处理轮子：wheel:{}" + wheel);
        if (productionLine.getCodeErrorNum(area) == 3) {
            productionLine.stopTask(area);
            eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_CODE_ERROR_MORE_THAN_THREE, true, area);
            productionLine.createAlarmEvent("条码拍照错误三次,已停止任务", area);
            return;
        }
        if (productionLine.getSnapErrorNum(area) == 3) {
            productionLine.stopTask(area);
            eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_SNAP_ERROR_MORE_THAN_THREE, true, area);
            productionLine.createAlarmEvent("卡扣识别错误三次,已停止任务", area);
            return;
        }
        String scanWheelNo = "";
        if (Objects.isNull(wheel)) {
            if (productionLine.isScanSignal(area)) {
                scanWheelNo = productionLine.getScanWheelNo(area);
                log.info("_______________视觉拍照信息1 :{}", scanWheelNo);
                scanWheelNo = productionLine.getScanWheelNo(area);
                log.info("_______________视觉拍照信息2 :{}", scanWheelNo);
                //过滤指令回复信息
                if (scanWheelNo.startsWith("000027")) {
                    return;
                }
                //保存视觉信息
                productionLine.saveVisualSense(scanWheelNo, area);
            }
            if (!StringUtils.hasText(scanWheelNo)) {
                productionLine.codeParsingFailed(area);
                productionLine.setCodeErrorNum(area, productionLine.getCodeErrorNum(area) + 1);
                productionLine.snapParsingFailed(area);
                productionLine.setSnapErrorNum(area, productionLine.getSnapErrorNum(area) + 1);
                productionLine.createAlarmEvent("条码数据为空", area);
                return;
            }
        }
        if (wheel == null) {
            int productType = productionLine.getProductType(area);
            if (scanWheelNo.startsWith("000058")) {
                //无条码无卡扣
                productionLine.codeParsingFailed(area);
                productionLine.setCodeErrorNum(area, productionLine.getCodeErrorNum(area) + 1);
                productionLine.snapParsingFailed(area);
                productionLine.setSnapErrorNum(area, productionLine.getSnapErrorNum(area) + 1);
                return;
            }
            if (scanWheelNo.startsWith("000081")) {
                //有条码无卡扣
                productionLine.snapParsingFailed(area);
                productionLine.setSnapErrorNum(area, productionLine.getSnapErrorNum(area) + 1);
                return;
            }
            if (scanWheelNo.startsWith("000087")) {
                //无条码有卡扣
                productionLine.codeParsingFailed(area);
                productionLine.setCodeErrorNum(area, productionLine.getCodeErrorNum(area) + 1);
                return;
            }
            if (scanWheelNo.startsWith("000110")) {
                //条码和卡扣识别成功
                String code = ScanCodeUtils.scanCodeToBarCodeAndColor2(scanWheelNo);
                log.info("解析出条码是{}", code);
                log.info("解析之前轮号：{}", scanWheelNo);
                String wheelNo = code.split("_")[0];
                log.info("解析出轮号是{}", wheelNo);
                String color = code.split("_")[1];
                log.info("解析出颜色是{}", color);
                if (color.equals("Z") || wheelNo.startsWith("#")) {
                    productionLine.createAlarmEvent("颜色||条码未解析成功,code:" + code, area);
                    productionLine.setCodeErrorNum(area, productionLine.getCodeErrorNum(area) + 1);
                    productionLine.codeParsingFailed(area);
                    return;
                }
                wheel = WheelHttp.queryIntermediateVO(wheelNo, productType);
                if (wheel.getVFree2().equals("B80") && color.equals("D")) {
                    //B80识别为粉色的 改判为红
                    color = "A";
                }
                if (wheel.getVFree2().equals("B40") && color.equals("A")) {
                    //B40识别为红色的 改判为粉
                    color = "D";
                }
                if (wheel.getVFree2().equals("B80/17") && color.equals("A")) {
                    //B80/17识别为红色的 改判为粉
                    color = "D";
                }
                if (wheel.getVFree2().equals("B60") && color.equals("D")) {
                    //B60识别为粉色的 改判为红
                    color = "A";
                }
                //工字轮高低位和PLC获取的高低位判断
                if (!isConsistent(wheel, productType)) {
                    productionLine.stopTask(area);
                    productionLine.createAlarmEvent("条码获取类型和PLC检测类型不一致", area);
                    eventCreater.createTriggerAlarm(AlarmTriggerType.PRODUCT_TYPE_ERROR, true, area);
                    return;
                }
                if (wheel.getBarCode().startsWith("XC") && !wheel.isAvailable()) {
                    productionLine.stopTask(area);
                    eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_AVAILABLE, true, area);
                    productionLine.createAlarmEvent("工字轮条码为成品,查询信息为不合格品,已停止系统,工字轮条码:" + wheelNo, area);
                    return;
                }
                productionLine.getPackProductionLine().getRobot().resetPackingStatus(area, wheel.getBarCode());
                if (wheel.getState() == WheelUseState.PACK_BOX.getNumber()) {
                    productionLine.getPackProductionLine().getRobot().createAlarmEvent("工字轮已装箱,信息已上传,已停止系统,工字轮条码:" + wheel.getBarCode(), area);
                    productionLine.stopTask(area);
                    return;
                }
                if (!productionLine.getPackProductionLine().getRobot().getTagValue(area)) {
                    productionLine.getPackProductionLine().getRobot().checkPackingStatus(area, wheel.getBarCode());
                }

                if (productionLine.getPackProductionLine().getRobot().getAlreadyPackingStatus(area)) {
                    productionLine.stopTask(area);
                    productionLine.getPackProductionLine().getRobot().createAlarmEvent("工字轮已装箱,已停止系统,工字轮条码:" + wheel.getBarCode(), area);
                    return;
                }
                BigDecimal torsionValue = wheel.getTorsionValue();
                log.info("torsionValue:" + torsionValue);
                if (torsionValue.compareTo(BigDecimal.valueOf(999.0)) == 0 && Objects.isNull(wheel.getConsumerName())) {
                    // 停止 触发报警
                    productionLine.stopTask(area);
                    eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_999, true, area);
                    productionLine.createAlarmEvent("网络错误,已停止任务,工字轮条码:" + wheelNo, area);
                    return;
                } else if (torsionValue.compareTo(BigDecimal.valueOf(9999.0)) == 0 && Objects.isNull(wheel.getConsumerName())) {
                    // 停止 触发
                    productionLine.stopTask(area);
                    eventCreater.createTriggerAlarm(AlarmTriggerType.WHEEL_ERROR_9999, true, area);
                    productionLine.createAlarmEvent("条码信息为空,已停止任务,工字轮条码:" + wheelNo, area);
                    return;
                } else {
                    if (wheel.getBarCode().startsWith("XD")) {
                        if (Objects.isNull(wheel.getFixedLength())) {
                            productionLine.createAlarmEvent("工字轮没有定长信息" + wheelNo, area);

                            wheel.setWheelTag("NOT-" + productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + 10600);
                        } else {
                            wheel.setWheelTag("NOT-" + productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + wheel.getFixedLength());
                        }
                    } else {
                        if (Objects.isNull(wheel.getFixedLength())) {
                            productionLine.createAlarmEvent("工字轮没有定长信息:" + wheelNo, area);
                            wheel.setWheelTag(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + 10600 + "-" + WheelSurfaceType.getByAB(color).getGr());
                        } else {
                            wheel.setWheelTag(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + wheel.getFixedLength() + "-" + WheelSurfaceType.getByAB(color).getGr());
                        }

                    }
                }
                if (wheelNo.length() == 13) {
                    wheelNo = wheelNo + "#####_" + color;
                }
                if (wheelNo.length() == 16) {
                    wheelNo = wheelNo + "##_" + color;
                }
                if (Objects.isNull(wheel.getFixedLength())) {
                    wheel.setWheelTagMap(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + 10600);
                } else {
                    wheel.setWheelTagMap(productionLine.getPackProductionLine().getRobot().getInvNameByInvBasDoc(wheel.getPkInvbasdoc()) + "-" + wheel.getVFree2() + "-" + wheel.getFixedLength());
                }
                wheel.setBarCodeBack(wheelNo);
                wheel.setAb(color);
                productionLine.codeParsingSucceeded(area);
                taskTicket.setWheel(wheel);
                productionLine.saveTicket(taskTicket, area);
            }

        } else {
            List<ProductBoxLocation> allProductBoxLocation = productionLine.getAllProductBoxLocation();
            if (allProductBoxLocation.isEmpty()) {
                productionLine.createAlarmEvent("当前区域的装箱区为空", area);
                productionLine.stopTask(area);
                log.info("装箱区为空");
                return;
            }
            int location = taskTicket.getLocation();
            if (location == 0) {
                List<ProductBoxLocation> canShuntBoxLocation = new ArrayList<>();
                for (ProductBoxLocation productBoxLocation : allProductBoxLocation) {
                    if (productBoxLocation.isEmpty()) {
                        continue;
                    }
                    if (ruleUtils.canShunt(productBoxLocation.getProductBox(), wheel)) {
                        canShuntBoxLocation.add(productBoxLocation);
                    }
                }
                if (canShuntBoxLocation.size() == 1) {
                    ProductBoxLocation productBoxLocation = canShuntBoxLocation.get(0);
                    if (line.equals("6") || line.equals("5")) {
                        if (productBoxLocation.getLocationNo() > 10) {
                            if (area == 3) {
                                location = 2;
                            } else {
                                location = 1;
                            }

                        } else {
                            if (area == 3) {
                                location = 1;
                            } else {
                                location = 2;
                            }
                        }
                    } else {
                        if (productBoxLocation.getLocationNo() > 10) {
                            location = 2;
                        } else {
                            location = 1;
                        }
                    }

                } else if (canShuntBoxLocation.size() > 1) {
                    //判断符合的装箱是不是在同一个区域
                    if (canShuntBoxLocation.size() == canShuntBoxLocation.stream().filter(ProductBoxLocation::isLeft).count() || canShuntBoxLocation.size() == canShuntBoxLocation.stream().filter(ProductBoxLocation::isRight).count()) {
                        if (line.equals("6") || line.equals("5")) {
                            if (canShuntBoxLocation.get(0).getLocationNo() > 10) {
                                if (area == 3) {
                                    location = 2;
                                } else {
                                    location = 1;
                                }
                            } else {
                                if (area == 3) {
                                    location = 1;
                                } else {
                                    location = 2;
                                }
                            }
                        } else {
                            if (canShuntBoxLocation.get(0).getLocationNo() > 10) {
                                location = 2;
                            } else {
                                location = 1;
                            }
                        }

                    } else {
                        location = ruleUtils.randomShunt(productionLine, area, line);
                    }
                }
                //都不符合 停机触发报警
                if (location == 0) {
                    productionLine.stopTask(area);
                    eventCreater.createTriggerAlarm(AlarmTriggerType.SHUNT_AREA_WHEEL_NO_SHUNT, true, area);
                    productionLine.createAlarmEvent("当前工字轮不符合装箱,已停止分流区:" + wheel.getWheelTag() + "-客户:" + wheel.getConsumerName(), area);
                    return;
                }
                taskTicket.setLocation(location);
                productionLine.saveTicket(taskTicket, area);
            }
            productionLine.wheelToLeftOrRight(location, wheel.getBarCodeBack(), area);
            log.info("分流区写入{}", ShuntAreaType.getByLocation(location));
            taskTicket.setState(TaskState.RUNING);
            taskTicket.setWheel(wheel);
            taskTicket.setLocation(location);
            //事件保存
            productionLine.handleShuntEvent(area, taskTicket);
        }

    }

    private boolean isConsistent(Wheel wheel, int productType) {
        if (wheel.getVFree2().startsWith("B80") && productType == 2) {
            return true;
        }
        return wheel.getVFree2().equals("B40") || wheel.getVFree2().equals("B60") && productType == 1;
    }
}
